import { _decorator, Node, Collider, Collider2D, v3, Vec2, Vec3 } from 'cc';
import { Unit } from './Unit';
import { ISpawnerEventCall, SpawnerCom, SpawnEvent } from './Component/SpawnerCom';
import { UnitPlanet } from './UnitPlanet';
import { Bullet } from './Bullet';
import AssetsMgr from '../Model/AssetsMgr';
import { UnitType } from '../Util/Global';
import { UnitAssault } from './UnitAssault';
import { Bullet_2 } from './Bullet_2';
const { ccclass, property } = _decorator;

@ccclass('UnitAssault_2')
export class UnitAssault_2 extends UnitAssault {

    @property(Node)
    public bulletSpwaningNode_1: Node = null;
    @property(Node)
    public bulletSpwaningNode_2: Node = null;

    /**副兵器工厂 */
    public arsenal_2: SpawnerCom = null;

    protected startLogic(): void {
        this.unitType = UnitType.UnitAssault_2;
        this._changeMoveInterval = 3;
        this.arsenal = this.node.getComponent(SpawnerCom);
        this.arsenal_2 = this.node.addComponent(SpawnerCom);

        this.arsenal.AddProduct(AssetsMgr.getUnitPrefab(UnitType.Bullet, 'Bullet2'));
        this.arsenal_2.AddProduct(AssetsMgr.getUnitPrefab(UnitType.Bullet, 'Bullet2'));

        this.arsenal.onSpawnEventCallback('UnitAssaultHandle', {
            SpawnEventCallback: this.SpawnEventCallback.bind(this)
        });
        this.arsenal_2.onSpawnEventCallback('UnitAssaultHandle', {
            SpawnEventCallback: this.SpawnEventCallback_2.bind(this)
        });
    }

    SpawnEventCallback(unit: Unit, event: SpawnEvent) {
        if (unit && event == SpawnEvent.SPAWNING) {
            this.bulletSpwaningNode_1.getWorldPosition(this.bulletSpawningPos);
            this.onBulletCreate(unit, this.bulletSpawningPos);
        }

        return true;
    };

    protected SpawnEventCallback_2(unit: Unit, event: SpawnEvent) {
        if (unit && event == SpawnEvent.SPAWNING) {
            this.bulletSpwaningNode_2.getWorldPosition(this.bulletSpawningPos);
            this.onBulletCreate(unit, this.bulletSpawningPos);
        }

        return true;
    };

    protected updateLogic(dt: number): void {

        let tooFar = this.TooFarFromParent();
        if (this.target && !this.target.death) {

            if (this.DistanceOther(this.target) > 200) {

                //当自己和目标相距太近时，不再改变方向
                this.ChangeChaseTargetDir();
                this.arsenal && this.arsenal.StartIdleWorkShop();
                this.arsenal_2 && this.arsenal_2.StartIdleWorkShop();
            }
        }
        else if (!tooFar) {

            this.target = this.FindTargetWeightAndNearest();
            if (!this.target || this.target.death) { //从父级获取目标
                if (this.parentUnit) {

                    this.target = (<UnitPlanet>this.parentUnit).FindEnemyNearest();
                }
            }
            if (this.target == this) {
                console.log('警告==>目标是自己！！？');
            }

            if (this.target) {
                this.ChangeChaseTargetDir();
            }
        }

        //太远了不管有没有目标在下次tick时回家
        if (tooFar) {
            this.TimeChangeMoveDir(true);
        }

        if (this._changeCount == 0) {
            this.TimeChangeMoveDir();
        }

        this.AutoMove();
    }

    ChangeChaseTargetDir() {
        //朝向子弹撞击预测位置
        let lookAt = this.CalculateAimingDir(this.selfBulletSpeed).normalize();
        // let lookAt = this.CalculateAimingDirection(this.selfBulletSpeed);
        this._moveVec.x = lookAt.x;
        this._moveVec.y = lookAt.y;
    }

    private _targetWorldDir: Vec3 = new Vec3();
    /** 计算瞄准方向，根据提供的自身速度和目标的速度预测撞击位置
     * @param selfSpeed 提供参与计算的自身速度
     */
    CalculateAimingDir(selfSpeed: number): Vec3 {

        this.target.node.getWorldPosition(this._targetWorldDir);
        let targetV = this.target.rigBody.linearVelocity.normalize();
        let dis = this.DistanceOther(this.target);
        let time = dis / selfSpeed;

        // let dr = this.GetDirToOther(this.target);
        // let d = 2 * (targetV.x * dr.x + targetV.y * dr.y);
        // let time = dis + d * d / selfSpeed / selfSpeed / 4;
        // time = Math.sqrt(time) + d / dis / 2;

        targetV.multiplyScalar(time * this.target.speed);
        this._targetWorldDir.x += targetV.x;
        this._targetWorldDir.y += targetV.y;
        this._targetWorldDir.subtract(this.unitWorldPos);//向量减法会改变自身

        return this._targetWorldDir.clone();
    }

    /**计算子弹发射角度 */
    // CalculateAimingDirection(bulletSpeed: number) {
    //     let distance = this.DistanceOther(this.target);
    //     let target_velocity = this.target.rigBody.linearVelocity.clone();
    //     let target_dir = target_velocity.clone().normalize();
    //     let target_v = target_velocity.length();

    //     this.target.node.getWorldPosition(this._targetWorldDir);
    //     this._targetWorldDir.subtract(this.unitWorldPos);

    //     let cosTheta = this._targetWorldDir.dot(this.ToVec3(target_dir));
    //     // 计算炮弹飞行时间
    //     let t = distance / (bulletSpeed - target_v * cosTheta);
    //     let target_move = target_dir.multiplyScalar(target_v * t);

    //     let dir = this.target.unitWorldPos_v2.add(target_move).subtract(this.unitWorldPos_v2).normalize();
    //     this._targetWorldDir.set(dir.x, dir.y);

    //     return this._targetWorldDir.clone();
    // }

    private selfBulletSpeed: number = 1;
    private bulletSpawningPos: Vec3 = new Vec3;
    protected onBulletCreate(unit: Unit, spawningPos?: Vec3) {
        if (!unit) {
            return;
        }
        let bullet = <Bullet_2>unit;
        this.selfBulletSpeed = bullet.maxSpeed;

        let enemy = this.target;
        if (enemy && !enemy.death) {

            // let targetDir = this.CalculateAimingDir(bullet.maxSpeed);
            // bullet.moveVec
            //     .set(targetDir.x, targetDir.y)
            //     .normalize()
            //     .multiplyScalar(bullet.maxSpeed);

            bullet.moveVec.set(this._moveVec.x, this._moveVec.y);

            bullet.node.setWorldPosition(spawningPos);

            bullet.parentUnit = this.parentUnit;//设置工厂作为父级
            // bullet.SetTarget(enemy);
        }
    }
}


